package com.coding.config;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.coding.entity.Message;
import com.coding.entity.vo.MsgVO;
import com.coding.service.impl.MessageServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
@Slf4j
public class ChatEndpoint extends TextWebSocketHandler {
    // 用户session集合
    private static final Map<Long, WebSocketSession> userSessions = new ConcurrentHashMap<>();

    // redis模板
    private static RedisTemplate<String, String> redisTemplate;

    private static MessageServiceImpl messageService;

    @Autowired
    public void setRedisTemplate(RedisTemplate<String, String> redisTemplate) {
        ChatEndpoint.redisTemplate = redisTemplate;
    }

    @Autowired
    public void setMessageService(MessageServiceImpl messageService) {
        ChatEndpoint.messageService = messageService;
    }

    /**
     * 连接建立成功
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        Long userId = getUserId(session);
        log.info("用户已连接: {}", userId);
        userSessions.put(userId, session);
        redisTemplate.opsForValue().set("USER_SESSION_" + userId, session.getId());
    }

    /**
     * 接收到消息
     * @param session
     * @param message
     * @throws Exception
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        Long userId = getUserId(session);
        log.info("收到来自用户的消息 {}: {}", userId, message.getPayload());
        try {

            if (message.getPayload().equals("ping")){
                session.sendMessage(new TextMessage("pong"));
                return;
            }

            // 将接收到的消息转换为Message对象
            MsgVO msg = JSON.parseObject(message.getPayload(), MsgVO.class);
            // 判断用户是否可以发送消息
            if (messageService.canSendMessage(userId, msg.getReceiverId())) {
                // 保存消息
                messageService.saveMessage(msg);
                // 获取接收者的session
                WebSocketSession receiverSession = userSessions.get(msg.getReceiverId());
                // 如果接收者的session存在且打开，则发送消息
                if (receiverSession != null && receiverSession.isOpen()) {
                    receiverSession.sendMessage(new TextMessage(JSON.toJSONString(msg)));
                    log.info("向用户发送消息 {}: {}", msg.getReceiverId(), JSON.toJSONString(msg));
                } else {
                    log.info("未找到或未打开接收方会话");
                }
            } else {
                log.info("用户 {} 无法发送消息给用户 {}", userId, msg.getReceiverId());
            }
        } catch (JSONException e) {
            session.sendMessage(new TextMessage("无效的邮件格式"));
            log.error("无效的邮件格式", e);
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        Long userId = getUserId(session);
        log.info("用户已断开连接: {}", userId);
        userSessions.remove(userId);
        redisTemplate.delete("USER_SESSION_" + userId);
    }

    private Long getUserId(WebSocketSession session) {
        // 从session中获取用户id
        return Long.parseLong((String) session.getAttributes().get("userId"));
    }
}
